package com.zwcl.payment.gateway.channel;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zwcl.common.core.exception.BusinessException;
import com.zwcl.payment.gateway.config.WeixinMchConfig;
import com.zwcl.payment.gateway.constants.PayCodeConstants;
import com.zwcl.payment.gateway.constants.PayConstants;
import com.zwcl.payment.gateway.constants.PayMessageConstants;
import com.zwcl.payment.gateway.entity.PaymentAccount;
import com.zwcl.payment.gateway.entity.PaymentLog;
import com.zwcl.payment.gateway.entity.PaymentMain;
import com.zwcl.payment.gateway.entity.PaymentRefund;
import com.zwcl.payment.gateway.enums.PayStatusEnum;
import com.zwcl.payment.gateway.enums.RefundStatusEnum;
import com.zwcl.payment.gateway.enums.WeixinRefundStatusEnum;
import com.zwcl.payment.gateway.enums.WeixinTradeStateEnum;
import com.zwcl.payment.gateway.mq.producer.MqProducer;
import com.zwcl.payment.gateway.service.*;
import com.zwcl.payment.gateway.service.base.PayWayAdapter;
import com.zwcl.payment.gateway.utils.RetryUtils;
import com.zwcl.payment.gateway.utils.WXPayUtil;
import com.zwcl.payment.gateway.vo.PaymentRespVO;
import com.zwcl.payment.gateway.vo.RefundRespVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;

/**
 * 微信小程序（普通商模式）
 * @Author guobaikun
 * @Date 2020/1/10 15:18
 * @Email kunye.guo@wetax.com.cn
 */
@Service("PayWayClient_1")
@Slf4j
public class WeixinMinaNormalService extends PayWayAdapter {

    @Autowired
    private PaymentMainService paymentService;
    @Autowired
    private PaymentLogService paymentLogService;
    //@Autowired
    //private WarnService warnService;
    @Autowired
    private WeixinMchConfig weixinMchConfig;
    @Autowired
    private PaymentRefundService paymentRefundService;
    @Autowired
    private PaymentRefundLogService paymentRefundLogService;
    @Autowired
    private PaymentAccountService paymentAccountService;

    @Autowired
    private MqProducer mqProducer;

    @Value("${zwclTrade.callback.prefix}")
    private String callbackUrlPrefix;

    public static final Integer expireMinute = 5;//默认支付订单超时时间，单位：分钟

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String pay(PaymentMain payment) {
        log.info("开始微信支付，请求参数：{}", JSON.toJSONString(payment));

        PaymentAccount account = paymentAccountService.getByType(payment.getMchType());
        TreeMap<String, String> requestParamMap = new TreeMap();
        requestParamMap.put("appid", account.getSubAppId());
        requestParamMap.put("mch_id", account.getSubMchId());
        requestParamMap.put("nonce_str", WXPayUtil.generateNonceStr());
        requestParamMap.put("body", payment.getProductName());
        requestParamMap.put("out_trade_no", payment.getPaymentNo());

        BigDecimal fee = payment.getPayAmount().multiply(new BigDecimal("100")).setScale(0, BigDecimal.ROUND_UP);
        requestParamMap.put("total_fee", fee.toString());
        requestParamMap.put("spbill_create_ip", "127.0.0.1");
        requestParamMap.put("time_expire", PayConstants.YYYYMMDDHHMMSS.format(LocalDateTime.now().plusMinutes(expireMinute)));
        requestParamMap.put("notify_url", callbackUrlPrefix + PayConstants.WEIXIN_MINA_NORMAL_PAY_CALLBACK_URL);
        requestParamMap.put("trade_type", "JSAPI");
        requestParamMap.put("openid", payment.getOpenId());
        requestParamMap.put("sign", WXPayUtil.generateSignature(requestParamMap, account.getSubSecretKey()));
        log.info("开始调微信支付接口，请求参数：{}", JSON.toJSONString(requestParamMap));
        Map<String, String> responseMap = WXPayUtil.request(null, weixinMchConfig.getPayUrl(), requestParamMap);
        log.info("微信支付接口，返回结果：{}", JSON.toJSONString(responseMap));

        //判断响应状态
        String exMsg = "请求参数："+ JSON.toJSONString(payment)+"<br>返回结果："+ JSON.toJSONString(responseMap);
        if (responseMap.get("return_code").equals("FAIL")) {
            //warnService.warn("发起微信小程序支付异常，paymentNo="+payment.getPaymentNo(), exMsg);
            throw new BusinessException(responseMap.get("return_msg"));
        }
        if (responseMap.get("result_code").equals("FAIL")) {
            //warnService.warn("发起微信小程序支付异常，paymentNo="+payment.getPaymentNo(), exMsg);
            throw new BusinessException(responseMap.get("err_code_des"));
        }
        //封装预支付信息
        TreeMap<String, String> payParamMap = new TreeMap();
        payParamMap.put("appId", account.getSubAppId());
        payParamMap.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000L));
        payParamMap.put("nonceStr", WXPayUtil.generateNonceStr());
        payParamMap.put("package", "prepay_id=" + responseMap.get("prepay_id"));
        payParamMap.put("signType", "MD5");
        payParamMap.put("paySign", WXPayUtil.generateSignature(payParamMap, account.getSubSecretKey()));
        log.info("发起微信支付结束，paymentNo={}，返回结果：{}", payment.getPaymentNo(), JSON.toJSONString(payParamMap));
        return JSON.toJSONString(payParamMap);
    }

    public void checkResponseStatus(Map<String, String> responseMap){
        if (responseMap.get("return_code").equals("FAIL")) {
            StringBuilder exceptionMsg = new StringBuilder().append("向微信发送请求失败：").append("return_code=")
                    .append(responseMap.get("return_code")).append("，return_msg=")
                    .append(responseMap.get("return_msg"));
            throw new BusinessException(exceptionMsg.toString());
        }
        if (responseMap.get("result_code").equals("FAIL")) {
            StringBuilder exceptionMsg = new StringBuilder().append("err_code=")
                    .append(responseMap.get("err_code")).append("，err_code_des=")
                    .append(responseMap.get("err_code_des"));
            throw new BusinessException(exceptionMsg.toString());
        }
    }

    /**
     * 支付回调
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    public void payCallback(Map<String, String> param) {
        log.info("微信支付回调开始......参数：{}", JSON.toJSONString(param));

        if(param.get("return_code").equals("FAIL")){
            throw new BusinessException("微信支付回调失败，原因："+param.get("return_msg"));
        }

        String paymentNo = param.get("out_trade_no");
        BigDecimal fee = new BigDecimal(param.get("total_fee")).divide(new BigDecimal("100"));
        String transactionId = param.get("transaction_id");
        String resultCode = param.get("result_code");
        String errCode = param.get("err_code");
        String errCodeDes = param.get("err_code_des");
        String timeEnd = param.get("time_end");//支付完成时间
        String bankType = param.get("bank_type");//银行类型

        //获取支付流水
        PaymentMain payment = paymentService.getByNo(paymentNo);
        if(payment==null){
            log.error("微信支付回调异常，未找到支付流水【{}】", paymentNo);
            //warnService.warn("微信支付回调异常，未找到支付流水【"+paymentNo+"】", JSON.toJSONString(param));
            return;
        }

        //校验签名
        PaymentAccount account = paymentAccountService.getByType(payment.getMchType());
        boolean correctSignature = WXPayUtil.isSignatureValid(param, account.getSubSecretKey());
        if (!correctSignature) {
            log.error("支付订单【{}】回调失败，原因：{}", paymentNo, PayMessageConstants.CHECK_SIGNATURE_FAILURE);
            //warnService.warn("微信支付回调异常，校验签名失败，paymentNo="+paymentNo, JSON.toJSONString(param));
            return;
        }

        //校验金额
        boolean correctFee = payment.getPayAmount().compareTo(fee) == 0;
        if (!correctFee) {
            log.error("支付订单【{}】回调失败，原因：{}", paymentNo, PayMessageConstants.CHECK_FEE_FAILURE);
            //warnService.warn("微信支付回调异常，校验金额失败，paymentNo="+paymentNo, JSON.toJSONString(param));
            return;
        }

        //校验订单状态
        if (Objects.equals(payment.getPayStatus(), PayStatusEnum.PAID.getValue())) {
            log.error("支付回调异常：【{}】该状态的订单不能支付", PayStatusEnum.getDesc(payment.getPayStatus()));
            return;
        }

        handlePayCallback(payment, transactionId, resultCode, errCode, errCodeDes, timeEnd, bankType, JSON.toJSONString(param));

        log.info("微信支付回调结束，paymentNo={}", payment.getPaymentNo());
    }

    /**
     * 支付回调处理
     * @param payment
     * @param transaction_id
     * @param resultCode
     * @param errCode
     * @param errCodeDes
     * @param timeEnd
     * @param bankType
     * @param param
     */
    public void handlePayCallback(PaymentMain payment, String transaction_id, String resultCode, String errCode, String errCodeDes,
                                  String timeEnd, String bankType, String param){
        if(Objects.equals(resultCode, WeixinTradeStateEnum.SUCCESS.getValue())){
            payment.setPayStatus(PayStatusEnum.PAID.getValue());
        } else if(StringUtils.equalsAny(resultCode, WeixinTradeStateEnum.NOTPAY.getValue(), WeixinTradeStateEnum.USERPAYING.getValue())){
            log.warn("支付订单【{}】第三方交易状态为：{}", payment.getPaymentNo(), resultCode);
            return;
        } else {
            payment.setPayStatus(PayStatusEnum.FAIL.getValue());
            payment.setErrCode(errCode);
            payment.setErrMsg(errCodeDes);
        }
        if(StringUtils.isNotBlank(timeEnd)){
            payment.setPayTime(LocalDateTime.parse(timeEnd, PayConstants.YYYYMMDDHHMMSS));//支付成功
        }
        payment.setCallbackTime(LocalDateTime.now());//回调时间
        payment.setTransactionId(transaction_id);
        payment.setBankType(bankType);

        //更新支付流水
        paymentService.update(
                new PaymentMain().setPayStatus(payment.getPayStatus())
                        .setTransactionId(payment.getTransactionId())
                        .setPayTime(payment.getPayTime())
                        .setCallbackTime(payment.getCallbackTime())
                        .setBankType(payment.getBankType())
                        .setErrCode(payment.getErrCode())
                        .setErrMsg(payment.getErrMsg()),
                new QueryWrapper<PaymentMain>().lambda().eq(PaymentMain::getPaymentNo, payment.getPaymentNo())
        );
        //添加日志
        paymentLogService.addLog(new PaymentLog().setPaymentNo(payment.getPaymentNo()).setPayStatus(payment.getPayStatus()).setOperationInfo(param));

        //发送mq回调
        PaymentRespVO vo =new PaymentRespVO();
        BeanUtils.copyProperties(payment,vo);
        mqProducer.bizMqPaymentCallback(vo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void refund(PaymentRefund paymentRefund) {
        log.info("开始微信退款，请求参数：{}", paymentRefund);

        PaymentAccount account = paymentAccountService.getByType(paymentRefund.getMchType());
        //判断商户是否支持退款
        if(!weixinMchConfig.isSupport(account.getSubMchId())){
            paymentRefundService.replyRefundErr(paymentRefund, "该笔订单的商户号无退款权限");
            return;
        }

        //退款订单状态为退款中
        paymentRefundService.update(
            new PaymentRefund().setRefundStatus(RefundStatusEnum.REFUNDING.getValue()),
            new UpdateWrapper<PaymentRefund>().lambda().eq(PaymentRefund::getRefundNo, paymentRefund.getRefundNo())
        );

        TreeMap<String, String> requestParamMap = new TreeMap();
        requestParamMap.put("appid", account.getSubAppId());
        requestParamMap.put("mch_id", account.getSubMchId());
        requestParamMap.put("nonce_str", WXPayUtil.generateNonceStr());
        requestParamMap.put("transaction_id", paymentRefund.getOutTradeNo());
        requestParamMap.put("out_refund_no", paymentRefund.getRefundNo());
        BigDecimal totalFee = paymentRefund.getPayAmount().multiply(new BigDecimal("100")).setScale(0, BigDecimal.ROUND_DOWN);
        requestParamMap.put("total_fee", totalFee.toString());
        BigDecimal refundFee = paymentRefund.getRefundAmount().multiply(new BigDecimal("100")).setScale(0, BigDecimal.ROUND_DOWN);
        requestParamMap.put("refund_fee", refundFee.toString());
        requestParamMap.put("notify_url", callbackUrlPrefix + PayConstants.WEIXIN_MINA_NORMAL_REFUND_CALLBACK_URL);
        requestParamMap.put("sign", WXPayUtil.generateSignature(requestParamMap, account.getSubSecretKey()));
        //添加日志
        paymentRefundLogService.addLog(paymentRefund.getRefundNo(), RefundStatusEnum.REFUNDING.getValue(), JSON.toJSONString(requestParamMap));
        //发起请求
        log.info("开始调微信退款接口，请求参数：{}", JSON.toJSONString(requestParamMap));
        Map<String, String> responseMap = WXPayUtil.request(account.getSubMchId(), weixinMchConfig.getRefundUrl(), requestParamMap);
        log.info("调微信退款接口，返回结果：{}", JSON.toJSONString(responseMap));

        //判断响应状态
        String rspCode = responseMap.get("return_code");
        if (Objects.equals(rspCode, "FAIL")) {
            String rspMsg = responseMap.get("return_msg");
            if(RetryUtils.refundRetry(paymentRefund.getRefundNo())){
                throw new BusinessException("向微信发送请求失败：return_code="+rspCode+",return_msg="+rspMsg);
            }
            paymentRefundService.replyRefundErr(paymentRefund, rspMsg, rspCode);
            return;
        }

        if (Objects.equals(responseMap.get("result_code"), "FAIL")) {
            String errCode = responseMap.get("err_code");
            String errCodeDes = responseMap.get("err_code_des");
            if(Objects.equals(errCode, "FREQUENCY_LIMITED")){//请求频率过高，触发限频
                if(RetryUtils.withholdRetry(paymentRefund.getRefundNo())){
                    throw new BusinessException("向微信发送请求失败：err_code="+errCode+",err_code_des="+errCodeDes);
                }
            }

            paymentRefundService.replyRefundErr(paymentRefund, errCodeDes, errCode);
            return;
        }

        log.info("微信退款发起成功，refundNo={}", paymentRefund.getRefundNo());
    }

    @Transactional(rollbackFor = Exception.class)
    public void refundCallback(Map<String, String> param) {
        log.info("微信退款回调开始......参数：{}", JSON.toJSONString(param));

        if(param.get("return_code").equals("FAIL")){
            throw new BusinessException("微信退款回调失败，原因："+param.get("return_msg"));
        }
        String secretKey = paymentAccountService.getSubSecretKey(param.get("mch_id"));
        Map<String, String> decodeRequestParamMap = WXPayUtil.decodeParamsCiperStr(param.get("req_info"), secretKey);
        log.info("微信退款回调解密后参数：{}", JSON.toJSONString(decodeRequestParamMap));
        param.putAll(decodeRequestParamMap);
        String refundNo = param.get("out_refund_no");
        BigDecimal refundFee = new BigDecimal(param.get("refund_fee")).divide(new BigDecimal("100"));
        String refundId = param.get("refund_id");
        String refundStatus = param.get("refund_status");
        String successTime = param.get("success_time");
        String settleRefundFee = param.get("settlement_refund_fee");
        String refundRecvAccout = param.get("refund_recv_accout");

        //退款流水是否存在
        PaymentRefund paymentRefund = paymentRefundService.getByNo(refundNo);
        if(paymentRefund==null){
            log.error("退款回调异常，未找到退款流水【{}】", refundNo);
            throw new BusinessException("未找到退款流水");
        }

        //校验订单状态
        if (!Objects.equals(paymentRefund.getRefundStatus(), RefundStatusEnum.REFUNDING.getValue())) {
            log.error("退款回调异常：【{}】该状态的订单不能退款", RefundStatusEnum.getDesc(paymentRefund.getRefundStatus()));
            return;
        }

        //校验金额
        boolean correctFee = paymentRefund.getRefundAmount().compareTo(refundFee) == 0;
        if (!correctFee) {
            log.error("退款订单【{}】回调失败，原因：{}", refundNo, PayMessageConstants.CHECK_FEE_FAILURE);
            return;
        }
        handleRefundCallback(paymentRefund, refundId, refundStatus, successTime, settleRefundFee, refundRecvAccout, JSON.toJSONString(param));

        log.info("微信退款回调结束，refundNo={}", paymentRefund.getRefundNo());
    }

    /**
     * 处理退款回调
     * @param paymentRefund
     * @param outRefundNo
     * @param refundStatus
     * @param successTime
     * @param settleRefundFee
     * @param refundRecvAccout
     * @param param
     */
    public void handleRefundCallback(PaymentRefund paymentRefund, String outRefundNo, String refundStatus,
                                     String successTime, String settleRefundFee, String refundRecvAccout, String param){
        if(refundStatus.equals(WeixinRefundStatusEnum.SUCCESS.getValue())){//退款成功
            paymentRefund.setRefundStatus(RefundStatusEnum.SUCCESS.getValue());
        }else if(refundStatus.equals(WeixinRefundStatusEnum.PROCESSING.getValue())){//退款处理中
            log.warn("退款订单【{}】第三方退款状态为：{}", paymentRefund.getRefundNo(), refundStatus);
            return;
        }else{//退款关闭或退款异常
            paymentRefund.setRefundStatus(RefundStatusEnum.FAIL.getValue());
            paymentRefund.setErrCode(refundStatus);
            paymentRefund.setErrMsg(WeixinRefundStatusEnum.getDesc(refundStatus));
        }
        if(StringUtils.isNotBlank(successTime)){
            paymentRefund.setRefundTime(LocalDateTime.parse(successTime, PayConstants.YYYYMMDDHHMMSS2));//退款成功
        }
        if(StringUtils.isNotBlank(settleRefundFee)){
            paymentRefund.setRefundAmount(new BigDecimal(settleRefundFee).divide(new BigDecimal("100")));
        }
        paymentRefund.setCallbackTime(LocalDateTime.now());//回调时间
        paymentRefund.setOutRefundNo(outRefundNo);
        paymentRefund.setRefundRecvAccout(refundRecvAccout);

        //更新退款流水
        paymentRefundService.update(
                new PaymentRefund().setRefundStatus(paymentRefund.getRefundStatus())
                        .setOutRefundNo(paymentRefund.getOutRefundNo())
                        .setRefundTime(paymentRefund.getRefundTime())
                        .setCallbackTime(paymentRefund.getCallbackTime())
                        .setRefundAmount(paymentRefund.getRefundAmount())
                        .setRefundRecvAccout(paymentRefund.getRefundRecvAccout())
                        .setErrMsg(paymentRefund.getErrMsg())
                        .setErrCode(paymentRefund.getErrCode()),
                new QueryWrapper<PaymentRefund>().lambda().eq(PaymentRefund::getRefundNo, paymentRefund.getRefundNo())
        );

        //添加日志
        paymentRefundLogService.addLog(paymentRefund.getRefundNo(), paymentRefund.getRefundStatus(), param);

        //业务内部异步回调
        RefundRespVO vo = new RefundRespVO();
        BeanUtils.copyProperties(paymentRefund,vo);
        mqProducer.bizMqRefundCallback(paymentRefund.getOrderType(),vo);
    }

    /**
     * 查询微信订单
     * @param paymentNo
     * @param mchType
     * @return
     */
    public Map<String, String> payQuery(String paymentNo, Integer mchType) {
        PaymentAccount account = paymentAccountService.getByType(mchType);
        TreeMap<String, String> requestParamMap = new TreeMap();
        requestParamMap.put("appid", account.getSubAppId());
        requestParamMap.put("mch_id", account.getSubMchId());
        requestParamMap.put("nonce_str", WXPayUtil.generateNonceStr());
        requestParamMap.put("out_trade_no", paymentNo);
        requestParamMap.put("sign", WXPayUtil.generateSignature(requestParamMap, account.getSubSecretKey()));
        log.info("开始调微信订单查询接口，请求参数：{}", JSON.toJSONString(requestParamMap));
        Map<String, String> responseMap = WXPayUtil.request(null, weixinMchConfig.getOrderQueryUrl(), requestParamMap);
        log.info("微信订单查询接口，返回结果：{}", JSON.toJSONString(responseMap));
        //判断响应状态
        checkResponseStatus(responseMap);

        return responseMap;
    }

    /**
     * 查询退款订单
     * @param refundNo
     * @param mchType
     * @return
     */
    public Map<String, String> refundQuery(String refundNo, Integer mchType) {
        PaymentAccount account = paymentAccountService.getByType(mchType);
        TreeMap<String, String> requestParamMap = new TreeMap();
        requestParamMap.put("appid", account.getSubAppId());
        requestParamMap.put("mch_id", account.getSubMchId());
        requestParamMap.put("nonce_str", WXPayUtil.generateNonceStr());
        requestParamMap.put("out_refund_no", refundNo);
        requestParamMap.put("sign", WXPayUtil.generateSignature(requestParamMap, account.getSubSecretKey()));
        log.info("开始调微信退款查询接口，请求参数：{}", JSON.toJSONString(requestParamMap));
        Map<String, String> responseMap = WXPayUtil.request(null, weixinMchConfig.getRefundQueryUrl(), requestParamMap);
        log.info("微信退款查询接口，返回结果：{}", JSON.toJSONString(responseMap));
        //判断响应状态
        checkResponseStatus(responseMap);

        return responseMap;
    }

    /**
     * 关闭订单
     * @param paymentNo
     * @param mchType
     * @return
     */
    public void closeOrder(String paymentNo, Integer mchType) {
        log.info("开始微信关闭订单，请求参数：paymentNo={}，mchType={}", paymentNo, mchType);

        PaymentAccount account = paymentAccountService.getByType(mchType);
        TreeMap<String, String> requestParamMap = new TreeMap();
        requestParamMap.put("appid", account.getSubAppId());
        requestParamMap.put("mch_id", account.getSubMchId());
        requestParamMap.put("nonce_str", WXPayUtil.generateNonceStr());
        requestParamMap.put("out_trade_no", paymentNo);
        requestParamMap.put("sign", WXPayUtil.generateSignature(requestParamMap, account.getSubSecretKey()));
        log.info("开始调微信支付接口，请求参数：{}", JSON.toJSONString(requestParamMap));
        Map<String, String> responseMap = WXPayUtil.request(null, weixinMchConfig.getCloseUrl(), requestParamMap);
        log.info("微信支付接口，返回结果：{}", JSON.toJSONString(responseMap));
        //判断响应状态
        if (responseMap.get("return_code").equals("FAIL")) {
            StringBuilder exceptionMsg = new StringBuilder().append("向微信发送请求失败：").append("return_code=")
                    .append(responseMap.get("return_code")).append("，return_msg=")
                    .append(responseMap.get("return_msg"));
            throw new BusinessException(exceptionMsg.toString());
        }
        if (responseMap.get("result_code").equals("FAIL")) {
            String errCode = responseMap.get("err_code");
            String errCodeDes = responseMap.get("err_code_des");
            if(Objects.equals(errCode, "ORDERPAID")){
                throw new BusinessException(PayCodeConstants.WEIXIN_ORDER_PAID,errCodeDes);
            }else if(Objects.equals(errCode, "ORDERCLOSED")){
                log.info("订单已关闭，paymentNo={}", paymentNo);
            }else{
                throw new BusinessException("微信关单失败：err_code="+errCode+",err_code_des="+errCodeDes);
            }
        }

        log.info("微信关闭订单成功，paymentNo={}", paymentNo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void payQueryHandle(PaymentMain payment) {
        Map<String, String> param = payQuery(payment.getPaymentNo(), payment.getMchType());
        String transactionId = param.get("transaction_id");
        String tradeState = param.get("trade_state");
        String timeEnd = param.get("time_end");//支付完成时间
        String bankType = param.get("bank_type");//银行类型
        handlePayCallback(payment, transactionId, tradeState, tradeState, WeixinTradeStateEnum.getDesc(tradeState), timeEnd, bankType, JSON.toJSONString(param));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void refundQueryHandle(PaymentRefund paymentRefund) {
        Map<String, String> param = refundQuery(paymentRefund.getRefundNo(), paymentRefund.getMchType());
        String refundId = param.get("refund_id_0");
        String refundStatus = param.get("refund_status_0");
        String successTime = param.get("refund_success_time_0");
        String settleRefundFee = param.get("settlement_refund_fee_0");
        String refundRecvAccout = param.get("refund_recv_accout_0");
        handleRefundCallback(paymentRefund, refundId, refundStatus, successTime, settleRefundFee, refundRecvAccout, JSON.toJSONString(param));
    }

}
